﻿using Cofe.Core.Property;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Cofe.Core.Utils
{
    public class EntryEqualityComparer : IEqualityComparer<IPropertyProvider>, IEqualityComparer<IPropertyHost>, IEqualityComparer<ICofeSystemInfo>
    {
        public static EntryEqualityComparer CompareParsePath
            = new EntryEqualityComparer() { ComparationMode = EntryComparationMode.ParsePath };

        public static EntryEqualityComparer CompareName
            = new EntryEqualityComparer() { ComparationMode = EntryComparationMode.Name };

        private EntryEqualityComparer() { }
        public EntryComparationMode ComparationMode { get; private set; }

        public bool Equals(IPropertyProvider x, IPropertyProvider y)
        {
            if (x == null || y == null)
                throw new ArgumentNullException(String.Format("One of the argument is null, {0}, {1}",
                    x, y));
            switch (ComparationMode)
            {
                case EntryComparationMode.ParsePath:
                    string xPath = x.GetOnePropertyAsync(CofeProperties.FullParseName).Result.ValueAsString;
                    string yPath = y.GetOnePropertyAsync(CofeProperties.FullParseName).Result.ValueAsString;
                    return xPath.Equals(yPath);
                case EntryComparationMode.Name:
                    string xName = x.GetOnePropertyAsync(CofeProperties.Name).Result.ValueAsString;
                    string yName = y.GetOnePropertyAsync(CofeProperties.Name).Result.ValueAsString;
                    return xName.Equals(yName);

                default: throw new NotSupportedException();
            }
        }

        public int GetHashCode(IPropertyProvider obj)
        {
            switch (ComparationMode)
            {
                case EntryComparationMode.ParsePath:
                    return obj.GetOnePropertyAsync(CofeProperties.FullParseName).Result.GetHashCode();
                case EntryComparationMode.Name:
                    return obj.GetOnePropertyAsync(CofeProperties.Name).Result.GetHashCode();

                default: throw new NotSupportedException();
            }
        }

        public bool Equals(IPropertyHost x, IPropertyHost y)
        {
            var xPP = x.PrimaryPropertyProvider ?? x.PropertyCache;
            var yPP = y.PrimaryPropertyProvider ?? y.PropertyCache;
            return Equals(xPP, yPP);
        }

        public int GetHashCode(IPropertyHost obj)
        {
            return GetHashCode(obj.PrimaryPropertyProvider);
        }

        public bool Equals(ICofeSystemInfo x, ICofeSystemInfo y)
        {
            return Equals(x.Properties, y.Properties);
        }

        public int GetHashCode(ICofeSystemInfo obj)
        {
            return GetHashCode(obj.Properties);
        }


    }
}
